// 声明类型的时候 如果没有标识类型 他是什么类型？
// 没有赋值的变量默认值是undefined 但是类型是any

// const 是常量意味着定义的值不会修改所以他的类型是一个字面量类型 . const声明变量必须复赋值
// let 声明变量 可以修改所以类型范围推到的结果会变大
const a1 = 1; // ===> 如果用常量，来自动推导，类型就是自变量 1
let a2 = 1;

// 联合类型...............................................................................
let strOrNum: string | number; // 如果是联合类型在使用方法的时候 只能采用公共的方法来使用
// 还是从安全性考虑， 在使用联合类型的时候 我门通过会先定义值，在使用. 保证安全

// 1） 指定类型在使用
// strOrNum = '1' // 赋值后会推断类型
// strOrNum.endsWith();
// strOrNum = 1 // 赋值后会推断类型
// strOrNum.toFixed()

// 2)联合类型 一般我们会基于联合类型 来扩展额外的类型
// 字面量类型。type 可以声明一个类型
// 字符串写法
type Direction = "up" | "down" | "right" | "left";
let direction: Direction = "left";

// 对象写法
// type 中定义的是类型 不是js中对象
// 用来保持一个对象内属性的统一
//可以利用联合类型来做到属性之间的互斥(可辨识联合类型)
type women =
  | { wealthy: true; waste: string }
  | { wealthy: false; norality: string };
let richWoman: women = { wealthy: true, waste: "购物和消费" };

let poorWoman: women = { wealthy: false, norality: "勤俭持家" };

// 断言的问题.............................................
// 我门断言类型后在使用 as断言成某种类型（一定是联合类型中的某一个） ! ===>非空断言， 表示这个值一定不是空的)
//  ! as不存在，结果你自己承担， ts不管了，你认为的一定有值
let ele = document.getElementById("app");
// ele!.style.background = 'red';
// as xxx 或者 <xxx>值  一般用于联合类型. 将大范围的类型 断言成子类型 <xxx>不推荐回和jxs语法冲突
(ele as HTMLElement).style.background = "red";

(strOrNum! as string).charCodeAt(0);
(<number>strOrNum!).toFixed(3);

//双重断言 我们可以把一个值 断言成any 在断言成某个类型//any 类型可以赋予给任何类型
let str: string | number;
str! as any as boolean;

// str! as boolean as true;

strOrNum! as unknown as boolean; // 双重断言，一般不建议使用，但是还会用到，破坏原有的关系

// !TS语法  ?js语法 链判断运算符（如果值有再去取值）

// ? 表示的是取值操作，不能赋值  ， ！表示某个变量一定存在
// ele?.style.background
// ?? js语法 合并空值运算符， 三元表达式 但是 false || 取的结果
// let val = 0 || 100 // ??除了 null 和 undefiend 其他都是true

export {};
